﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Hardcodet.Wpf.TaskbarNotification;

namespace Swan.SwanWakeUp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private static TaskbarIcon icon;

        public static TaskbarIcon NotifyIcon
        {
            get
            {
                if (icon == null)
                {
                    icon = new TaskbarIcon()
                    {
                        ToolTipText = "SwanWakeUp",
                    };
                }

                return icon;
            }
        }

        // {9D2AEC79-E021-47D4-A301-BAEE348CB153}
        static readonly Guid appGuidConst = new Guid("9D2AEC79-E021-47D4-A301-BAEE348CB153");

        protected override void OnStartup(StartupEventArgs e)
        {
            // get application GUID as defined in AssemblyInfo.cs
            string appGuid = appGuidConst.ToString(); // ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();

            // unique id for global mutex - Global prefix means it is global to the machine
            string mutexId = string.Format("Global\\{{{0}}}", appGuid);

            using (var mutex = new Mutex(false, mutexId))
            {
                // edited by Jeremy Wiebe to add example of setting up security for multi-user usage
                // edited by 'Marc' to work also on localized systems (don't use just "Everyone") 
                var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
                var securitySettings = new MutexSecurity();
                securitySettings.AddAccessRule(allowEveryoneRule);
                mutex.SetAccessControl(securitySettings);

                // edited by acidzombie24
                var hasHandle = false;
                try
                {
                    try
                    {
                        // note, you may want to time out here instead of waiting forever
                        // edited by acidzombie24
                        // mutex.WaitOne(Timeout.Infinite, false);
                        hasHandle = mutex.WaitOne(5000, false);
                        if (hasHandle == false)
                            throw new TimeoutException("Timeout waiting for exclusive access");
                    }
                    catch (AbandonedMutexException)
                    {
                        // Log the fact the mutex was abandoned in another process, it will still get aquired
                        hasHandle = true;
                    }

                    // Perform your work here.
                }
                finally
                {
                    // edited by acidzombie24, added if statemnet
                    if (hasHandle)
                        mutex.ReleaseMutex();
                }
            }
            //AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            //Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
            try
            {
                bool runApp = true;
                if (e.Args.Length > 0)
                {
                    runApp = HandleArgs(e.Args);
                }

                if (runApp)
                {
                    var window = new MainWindow();
                    Application.Current.MainWindow = window;
                    window.Loaded += (o, e2) =>
                        {
                            icon = new TaskbarIcon()
                            {
                                Icon = Swan.SwanWakeUp.Properties.Resources.clock,
                                ToolTipText = "SwanWakeUp",
                            };
                        };
                    window.ShowDialog();
                }
                else
                {
                    Application.Current.Shutdown(0);
                }

                base.OnStartup(e);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("SwanWakeUp.App.Startup", "Error: " + ex.Message, EventLogEntryType.Error);
                MessageBox.Show("Critical error: " + ex.Message);
            }
        }

        private static bool HandleArgs(string[] args)
        {
            if (args.Length > 0)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    switch (args[i])
                    {
                        case "-a":
                            EventLog.WriteEntry("SwanWakeUp", "Starting alarm at " + DateTime.Now, EventLogEntryType.SuccessAudit);
                            HandleAlarmActions(args[++i]);
                            break;
                        default:
                            break;
                    }
                }
                return true;
            }

            return true;
        }

        private static bool HandleAlarmActions(string actionType)
        {
            switch (actionType)
            {
                case "Default":
                    var a = new AlarmActions.DefaultAction();
                    a.Run();
                    break;
                default:
                    break;
            }

            return true;
        }

    }
}
